package org.ucas.kgraph.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.ucas.kgraph.entity.Relation;
import org.ucas.kgraph.entity.RelationType;

import java.util.List;

@Repository
public interface RelationDao extends JpaRepository<Relation, Long> {

  /**
   * @param parentId
   * @return parentId的所有直接子节点
   */
  @Query("SELECT r.leftEnd FROM Relation r WHERE r.rightEnd = ?1 AND r.category = 0")
  public List<Long> childIds(Long termId);

  /**
   * @param termId
   * @return 词条的所有父节点
   */
  @Query("SELECT r.rightEnd FROM Relation r WHERE r.leftEnd = ?1 AND r.category = 0")
  public List<Long> parentIds(Long termId);

  @Query("SELECT CASE WHEN (r.leftEnd = ?1) THEN r.rightEnd ELSE r.leftEnd END" +
          " FROM Relation r WHERE ( r.leftEnd = ?1 OR r.rightEnd = ?1 ) " +
          "AND r.category = 1")
  public List<Long> linkedIds(Long termId);

  @Query(" FROM Relation r WHERE ( r.leftEnd = ?" +
          "1 OR r.rightEnd = ?1 ) " +
          "AND r.category = 1")
  public List<Relation> links(Long termId);


  @Modifying
  @Query("DELETE FROM Relation r WHERE r.leftEnd = ?1 OR r.rightEnd = ?1")
  public void deleteByTerm(Long termId);

  @Query("FROM Relation r WHERE r.leftEnd = ?1 AND r.rightEnd = ?2 AND r.category = ?3")
  public Relation findByCombination(Long left, Long right, RelationType category);

  @Query("FROM Relation r WHERE r.rightEnd in :parents AND r.category = 0")
  public List<Relation> childsInBatch(@Param("parents") List<Long> parentIds);

  /**
   * @param terms
   * @param minLevel
   * @param maxLevel
   * @return 有一端在terms中且处于给定的level区间的关联关系
   */
  @Query("FROM Relation r WHERE (r.leftEnd in :terms OR r.rightEnd in :terms )" +
          "AND (r.level > :minLevel AND r.level < :maxLevel OR r.level = -1)")
  public List<Relation> linksInBatchBetweenLevel(@Param("terms") List<Long> terms,
                                                 @Param("minLevel") int minLevel,
                                                 @Param("maxLevel") int maxLevel);

  /**
   * @param terms
   * @return 两端均在terms中的关联关系
   */
  @Query("FROM Relation r WHERE r.leftEnd in :terms AND r.rightEnd in :terms")
  public List<Relation> strictLinksInBatch(@Param("terms") List<Long> terms);
  
  
  @Query("FROM Relation r WHERE (r.leftEnd =?1 OR r.rightEnd =?1) AND r.category=?2")
  public List<Relation> findAllLinks(Long id,RelationType link);
}
